package com.hmdp.task;

import cn.hutool.json.JSONUtil;
import com.hmdp.entity.SeckillVoucher;
import com.hmdp.entity.Shop;
import com.hmdp.entity.VoucherOrder;
import com.hmdp.mapper.SeckillVoucherMapper;
import com.hmdp.mapper.ShopMapper;
import com.hmdp.mapper.VoucherOrderMapper;
import com.hmdp.service.IShopService;
import com.hmdp.utils.RedisData;
import com.hmdp.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author TJS
 * @Description
 * @create 2023/1/15 16:14
 */
@Service
public class InitTask {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Resource
    private SeckillVoucherMapper seckillVoucherMapper;

    @Resource
    private VoucherOrderMapper voucherOrderMapper;

    @Resource
    private ShopMapper shopMapper;

    @PostConstruct
    public void init(){
        /*
            缓存 优惠券库存
         */
        List<SeckillVoucher> seckillVouchers = seckillVoucherMapper.queryAll();
        seckillVouchers.forEach((seckillVoucher)->{
            Integer stock = seckillVoucher.getStock();
            Long voucherId = seckillVoucher.getVoucherId();
            redisTemplate.opsForValue().set("seckill:stock:"+voucherId,stock.toString());
            redisTemplate.opsForSet().add("seckill:order:"+voucherId,"init");
        });

        /*
            用于redis订单id 初始化：优惠券set集合，存储useId，用于保证一人一单
         */
        List<VoucherOrder> voucherOrders = voucherOrderMapper.queryAll();
        voucherOrders.forEach((voucherOrder)->{
            Long userId = voucherOrder.getUserId();
            Long voucherId = voucherOrder.getVoucherId();
            redisTemplate.opsForSet().add("seckill:order:"+voucherId,userId.toString());
        });

        /*
            用于逻辑过期初始化
         */
        List<Shop> shopList = shopMapper.queryAll();
        shopList.forEach((shop)->{
            RedisData<Shop> redisData = new RedisData<>();
            redisData.setData(shop);
            redisData.setExpireTime(LocalDateTime.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5)));
            redisTemplate.opsForValue().setIfAbsent("shop:cache:"+shop.getId(),JSONUtil.toJsonStr(redisData));
        });

        /*
            用于初始化店铺坐标信息到redis中 geo数据结构
         */
        Map<Long, List<Shop>> shopTypeMap = shopList.stream().collect(Collectors.groupingBy(Shop::getTypeId));

        for (Map.Entry<Long, List<Shop>> entry : shopTypeMap.entrySet()) {
            Long shopTypeId = entry.getKey();
            List<Shop> shops = entry.getValue();

            List<RedisGeoCommands.GeoLocation<String>> locations = shops.stream().map(shop -> {
                Long shopId = shop.getId();
                return new RedisGeoCommands.GeoLocation<>(shopId.toString(), new Point(shop.getX(), shop.getY()));
            }).collect(Collectors.toList());
            redisTemplate.opsForGeo().add("shop:geo:"+shopTypeId,locations);
        }
    }
}
